package jmm;


import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

class MyData {
    final AtomicInteger number = new AtomicInteger();
    public void oper() {
        try { TimeUnit.MILLISECONDS.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); }
        this.number.set(20);
    }
    public void incr() {
        this.number.getAndIncrement();
        // 自加不是原子操作，一共三步：获取count，count+1，count赋值
        // 线程的工作一定要将数据拷贝到工作内存
    }
}

public class VolatileDemo {
    public static void main(String[] args) {
    }
    // 出现了写覆盖
    private static void nonAtomic() {
        MyData data = new MyData();
        for (int i = 0; i < 20; i++) {
            new Thread(() -> {
                for (int j = 0; j < 1000; j++) {
                    data.incr();
                }
            }).start();
        }

        // 基本的线程有两个: main + GC
        while (Thread.activeCount() > 2) {
            Thread.yield(); // 前边的计算操作没有完成时，礼让
        }
        System.out.println(data.number.get());
    }

    // 可见性
    // 当变量改变后，及时通知其他线程主内存中的值被修改
    private static void canSee() {
        MyData data = new MyData();
        new Thread(data::oper).start();

        while (data.number.get() == 0);   // 若不可见，则main线程的资源一直没有被改写
        System.out.println("main finish");
    }
}
